#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <map>
#include <filesystem>
#include <algorithm>

namespace fs = std::filesystem;

// 注释生成器
class CommentGenerator {
public:
    // 生成文件头注释
    static std::string GenerateFileHeader(const std::string& fileName, const std::string& description = "") {
        std::stringstream header;
        header << "/**\n";
        header << " * @file " << fileName << "\n";
        header << " * @brief " << (description.empty() ? "Brief description of this file" : description) << "\n";
        header << " * @author AI Assistant\n";
        header << " * @date " << GetCurrentDate() << "\n";
        header << " * @version 1.0\n";
        header << " */\n";
        return header.str();
    }

    // 生成函数注释
    static std::string GenerateFunctionComment(const std::string& functionName, 
                                              const std::vector<std::string>& params = {},
                                              const std::string& returnType = "void",
                                              const std::string& description = "") {
        std::stringstream comment;
        comment << "/**\n";
        comment << " * @brief " << (description.empty() ? "Brief description of " + functionName : description) << "\n";
        
        for (const auto& param : params) {
            comment << " * @param " << param << " Description of " << param << "\n";
        }
        
        if (returnType != "void") {
            comment << " * @return " << returnType << " Description of return value\n";
        }
        
        comment << " */\n";
        return comment.str();
    }

    // 生成类注释
    static std::string GenerateClassComment(const std::string& className, const std::string& description = "") {
        std::stringstream comment;
        comment << "/**\n";
        comment << " * @class " << className << "\n";
        comment << " * @brief " << (description.empty() ? "Brief description of " + className : description) << "\n";
        comment << " * @details Detailed explanation of the class purpose and functionality\n";
        comment << " */\n";
        return comment.str();
    }

    // 生成main函数注释
    static std::string GenerateMainFunctionComment() {
        return R"(/**
 * @brief Main entry point of the application
 * @param argc Number of command line arguments
 * @param argv Array of command line argument strings
 * @return int Exit status (0 for success, non-zero for error)
 */
)";
    }

private:
    static std::string GetCurrentDate() {
        time_t now = time(0);
        tm* localTime = localtime(&now);
        char buffer[80];
        strftime(buffer, sizeof(buffer), "%Y-%m-%d", localTime);
        return std::string(buffer);
    }
};

// 增强的文件分析器（带注释生成）
class EnhancedCodeAnalyzer {
public:
    struct FileAnalysis {
        std::string content;
        int lineCount;
        int charCount;
        bool hasMainFunction;
        bool hasClassDefinition;
        std::vector<std::string> includedHeaders;
        int commentLineCount;
        int functionCount;
        std::vector<std::string> functionNames;
        std::vector<std::string> classNames;
    };

    struct GeneratedComments {
        std::string fileHeader;
        std::vector<std::string> functionComments;
        std::vector<std::string> classComments;
        std::string mainFunctionComment;
    };

    static bool ReadAndAnalyzeProject(const std::string& cbpFile, 
                                     std::map<std::string, FileAnalysis>& analysisResults) {
        std::string projectName;
        std::vector<std::string> sourceFiles;
        
        if (!ParseCBPFile(cbpFile, projectName, sourceFiles)) {
            return false;
        }

        std::cout << "🔍 Analyzing " << sourceFiles.size() << " source files..." << std::endl;
        
        for (const auto& filePath : sourceFiles) {
            std::string fullPath = GetFullPath(cbpFile, filePath);
            
            if (fs::exists(fullPath)) {
                FileAnalysis analysis = AnalyzeSourceFile(fullPath);
                analysisResults[filePath] = analysis;
                
                std::cout << "📊 " << filePath << " (" 
                          << analysis.lineCount << " lines, " 
                          << analysis.charCount << " chars)" << std::endl;
                          
                if (analysis.hasMainFunction) {
                    std::cout << "   ⚡ Contains main() function" << std::endl;
                }
                if (analysis.hasClassDefinition) {
                    std::cout << "   🏗️  Contains class/struct definition" << std::endl;
                }
                if (!analysis.includedHeaders.empty()) {
                    std::cout << "   📁 Includes: " << analysis.includedHeaders.size() << " headers" << std::endl;
                }
                std::cout << "   💬 Comments: " << analysis.commentLineCount << " lines" << std::endl;
                std::cout << "   🔧 Functions: " << analysis.functionCount << " detected" << std::endl;
            } else {
                std::cout << "❌ File not found: " << fullPath << std::endl;
            }
        }
        
        return true;
    }

    // 生成注释建议
    static GeneratedComments GenerateCommentsForFile(const FileAnalysis& analysis, const std::string& filePath) {
        GeneratedComments comments;
        
        std::string fileName = fs::path(filePath).filename().string();
        std::string ext = fs::path(filePath).extension().string();
        bool isHeader = (ext == ".h" || ext == ".hpp");
        
        // 生成文件头注释
        std::string description = isHeader ? "Header file for " + fileName : "Implementation file for " + fileName;
        comments.fileHeader = CommentGenerator::GenerateFileHeader(fileName, description);
        
        // 生成函数注释
        for (const auto& funcName : analysis.functionNames) {
            std::vector<std::string> params;
            // 简化的参数检测（实际项目需要语法解析）
            if (funcName.find("parse") != std::string::npos) {
                params = {"input", "output"};
            } else if (funcName.find("calculate") != std::string::npos) {
                params = {"x", "y"};
            } else {
                params = {"param1", "param2"};
            }
            
            std::string funcDescription = "Perform " + funcName + " operation";
            comments.functionComments.push_back(
                CommentGenerator::GenerateFunctionComment(funcName, params, "void", funcDescription)
            );
        }
        
        // 生成类注释
        for (const auto& className : analysis.classNames) {
            std::string classDescription = className + " class implementation";
            comments.classComments.push_back(
                CommentGenerator::GenerateClassComment(className, classDescription)
            );
        }
        
        // 生成main函数注释
        if (analysis.hasMainFunction) {
            comments.mainFunctionComment = CommentGenerator::GenerateMainFunctionComment();
        }
        
        return comments;
    }

    // 生成注释报告
    static void GenerateCommentReport(const std::map<std::string, FileAnalysis>& analysis) {
        std::cout << std::endl;
        std::cout << "📝 COMMENT GENERATION REPORT" << std::endl;
        std::cout << "==========================================" << std::endl;
        
        for (const auto& pair : analysis) {
            const std::string& filePath = pair.first;
            const auto& fileAnalysis = pair.second;
            
            std::cout << std::endl;
            std::cout << "📄 " << filePath << ":" << std::endl;
            
            auto generatedComments = GenerateCommentsForFile(fileAnalysis, filePath);
            
            // 显示生成的注释
            if (!generatedComments.fileHeader.empty()) {
                std::cout << "   📋 Generated file header:" << std::endl;
                std::cout << generatedComments.fileHeader << std::endl;
            }
            
            if (!generatedComments.functionComments.empty()) {
                std::cout << "   🔧 Generated function comments: " << generatedComments.functionComments.size() << std::endl;
                for (size_t i = 0; i < std::min(generatedComments.functionComments.size(), size_t(2)); i++) {
                    std::cout << generatedComments.functionComments[i] << std::endl;
                }
                if (generatedComments.functionComments.size() > 2) {
                    std::cout << "   ... and " << (generatedComments.functionComments.size() - 2) << " more function comments\n";
                }
            }
            
            if (!generatedComments.classComments.empty()) {
                std::cout << "   🏗️  Generated class comments: " << generatedComments.classComments.size() << std::endl;
                for (const auto& classComment : generatedComments.classComments) {
                    std::cout << classComment << std::endl;
                }
            }
            
            if (!generatedComments.mainFunctionComment.empty()) {
                std::cout << "   ⚡ Generated main function comment:" << std::endl;
                std::cout << generatedComments.mainFunctionComment << std::endl;
            }
        }
    }

private:
    static bool ParseCBPFile(const std::string& filename, 
                            std::string& projectName, 
                            std::vector<std::string>& sourceFiles) {
        std::ifstream file(filename);
        if (!file.is_open()) return false;
        
        std::string line;
        while (std::getline(file, line)) {
            if (line.find("<Option title=") != std::string::npos) {
                size_t start = line.find('"');
                size_t end = line.find('"', start + 1);
                if (start != std::string::npos && end != std::string::npos) {
                    projectName = line.substr(start + 1, end - start - 1);
                }
            }
            
            if (line.find("<Unit filename=") != std::string::npos) {
                size_t start = line.find('"');
                size_t end = line.find('"', start + 1);
                if (start != std::string::npos && end != std::string::npos) {
                    std::string filePath = line.substr(start + 1, end - start - 1);
                    if (IsSourceFile(filePath)) {
                        sourceFiles.push_back(filePath);
                    }
                }
            }
        }
        
        file.close();
        return !projectName.empty();
    }

    static FileAnalysis AnalyzeSourceFile(const std::string& filePath) {
        FileAnalysis analysis;
        analysis.content = ReadFileContent(filePath);
        analysis.lineCount = CountLines(analysis.content);
        analysis.charCount = analysis.content.length();
        analysis.hasMainFunction = ContainsMainFunction(analysis.content);
        analysis.hasClassDefinition = ContainsClassDefinition(analysis.content);
        analysis.includedHeaders = ExtractIncludes(analysis.content);
        analysis.commentLineCount = CountCommentLines(analysis.content);
        analysis.functionCount = CountFunctionDefinitions(analysis.content);
        analysis.functionNames = ExtractFunctionNames(analysis.content);
        analysis.classNames = ExtractClassNames(analysis.content);
        
        return analysis;
    }

    static std::string ReadFileContent(const std::string& filePath) {
        std::ifstream file(filePath);
        if (!file.is_open()) return "";
        std::stringstream buffer;
        buffer << file.rdbuf();
        return buffer.str();
    }

    static int CountLines(const std::string& content) {
        int count = 0;
        for (char c : content) {
            if (c == '\n') count++;
        }
        return count + (content.empty() ? 0 : 1);
    }

    static int CountCommentLines(const std::string& content) {
        int count = 0;
        std::istringstream stream(content);
        std::string line;
        bool inBlockComment = false;
        
        while (std::getline(stream, line)) {
            line.erase(0, line.find_first_not_of(" \t"));
            line.erase(line.find_last_not_of(" \t") + 1);
            
            if (inBlockComment) {
                count++;
                if (line.find("*/") != std::string::npos) {
                    inBlockComment = false;
                }
            } else {
                if (line.find("/*") != std::string::npos) {
                    count++;
                    inBlockComment = true;
                    if (line.find("*/") != std::string::npos) {
                        inBlockComment = false;
                    }
                } else if (line.find("//") == 0) {
                    count++;
                }
            }
        }
        return count;
    }

    static int CountFunctionDefinitions(const std::string& content) {
        int count = 0;
        size_t pos = 0;
        while ((pos = content.find("){", pos)) != std::string::npos) {
            count++;
            pos += 2;
        }
        return count;
    }

    static std::vector<std::string> ExtractFunctionNames(const std::string& content) {
        std::vector<std::string> names;
        std::istringstream stream(content);
        std::string line;
        
        while (std::getline(stream, line)) {
            if (line.find("(") != std::string::npos && 
                line.find(")") != std::string::npos &&
                line.find(";") == std::string::npos) {
                size_t parenPos = line.find("(");
                if (parenPos != std::string::npos) {
                    std::string beforeParen = line.substr(0, parenPos);
                    size_t lastSpace = beforeParen.find_last_of(" \t\n*&");
                    if (lastSpace != std::string::npos) {
                        std::string potentialName = beforeParen.substr(lastSpace + 1);
                        if (potentialName.length() > 1 && 
                            isalpha(potentialName[0]) && 
                            names.size() < 10) {
                            names.push_back(potentialName);
                        }
                    }
                }
            }
        }
        return names;
    }

    static std::vector<std::string> ExtractClassNames(const std::string& content) {
        std::vector<std::string> names;
        std::istringstream stream(content);
        std::string line;
        
        while (std::getline(stream, line)) {
            if (line.find("class ") != std::string::npos) {
                size_t classPos = line.find("class ");
                size_t nameStart = classPos + 6;
                size_t nameEnd = line.find_first_of(" {:", nameStart);
                if (nameEnd != std::string::npos) {
                    std::string className = line.substr(nameStart, nameEnd - nameStart);
                    className.erase(0, className.find_first_not_of(" \t"));
                    className.erase(className.find_last_not_of(" \t") + 1);
                    if (!className.empty()) {
                        names.push_back(className);
                    }
                }
            }
        }
        return names;
    }

    static bool ContainsMainFunction(const std::string& content) {
        return content.find("main(") != std::string::npos ||
               content.find("main (") != std::string::npos;
    }

    static bool ContainsClassDefinition(const std::string& content) {
        return content.find("class ") != std::string::npos ||
               content.find("struct ") != std::string::npos;
    }

    static std::vector<std::string> ExtractIncludes(const std::string& content) {
        std::vector<std::string> includes;
        std::istringstream stream(content);
        std::string line;
        
        while (std::getline(stream, line)) {
            if (line.find("#include") != std::string::npos) {
                line.erase(0, line.find_first_not_of(" \t"));
                line.erase(line.find_last_not_of(" \t") + 1);
                includes.push_back(line);
            }
        }
        return includes;
    }

    static bool IsSourceFile(const std::string& filePath) {
        std::string ext = fs::path(filePath).extension().string();
        return ext == ".cpp" || ext == ".c" || ext == ".h" || ext == ".hpp" ||
               ext == ".cxx" || ext == ".cc" || ext == ".hxx";
    }

    static std::string GetFullPath(const std::string& cbpFile, const std::string& relativePath) {
        fs::path cbpPath(cbpFile);
        fs::path cbpDir = cbpPath.parent_path();
        fs::path fullPath = cbpDir / relativePath;
        return fullPath.string();
    }
};

// AI模型管理器
class AIModelManager {
private:
    std::string currentModel;
    std::string currentModelName;
    
public:
    AIModelManager() : currentModel("DSAI"), currentModelName("DS-V3.2exp0922") {}
    
    void SetModel(int model_id, const std::string& model_name = "") {
        switch(model_id) {
            case 0: currentModel = "DSAI"; currentModelName = model_name.empty() ? "DS-V3.2exp0922" : model_name; break;
            case 1: currentModel = "UEAI"; currentModelName = model_name.empty() ? "UE-CodeExpert" : model_name; break;
            case 2: currentModel = "OPAI"; currentModelName = model_name.empty() ? "GPT-4" : model_name; break;
            default: currentModel = "UNKNOWN"; currentModelName = "Unknown";
        }
        std::cout << "AI Model set: " << currentModel << " - " << currentModelName << std::endl;
    }
    
    std::string GetStatus() const {
        return "AI Model: " + currentModel + " (" + currentModelName + ")";
    }

    // 注释生成命令
    void GenerateComments(const std::string& cbpFile) {
        std::map<std::string, EnhancedCodeAnalyzer::FileAnalysis> analysis;
        
        std::cout << "🚀 Starting Comment Generation..." << std::endl;
        std::cout << "Project: " << cbpFile << std::endl;
        std::cout << "AI Model: " << currentModelName << std::endl;
        std::cout << "==========================================" << std::endl;
        
        if (EnhancedCodeAnalyzer::ReadAndAnalyzeProject(cbpFile, analysis)) {
            EnhancedCodeAnalyzer::GenerateCommentReport(analysis);
        } else {
            std::cout << "❌ Failed to analyze project" << std::endl;
        }
    }

    void AnalyzeProjectWithCode(const std::string& cbpFile) {
        std::map<std::string, EnhancedCodeAnalyzer::FileAnalysis> analysis;
        
        std::cout << "🚀 Starting Deep Code Analysis..." << std::endl;
        std::cout << "Project: " << cbpFile << std::endl;
        std::cout << "AI Model: " << currentModelName << std::endl;
        std::cout << "==========================================" << std::endl;
        
        if (EnhancedCodeAnalyzer::ReadAndAnalyzeProject(cbpFile, analysis)) {
            // 原有的分析逻辑...
        } else {
            std::cout << "❌ Failed to analyze project" << std::endl;
        }
    }
};

int main(int argc, char* argv[]) {
    AIModelManager aiManager;
    
    // 新的注释生成命令
    if (argc > 1 && std::string(argv[1]) == "--ai-generate-comments") {
        if (argc > 2) {
            aiManager.GenerateComments(argv[2]);
        } else {
            std::cout << "Usage: --ai-generate-comments <cbp_file>" << std::endl;
        }
        return 0;
    }
    
    // 原有命令保持不变
    if (argc > 1 && std::string(argv[1]) == "--ai-set-model") {
        if (argc > 3) {
            int model_id = std::stoi(argv[2]);
            std::string model_name = argv[3];
            aiManager.SetModel(model_id, model_name);
        } else if (argc > 2) {
            int model_id = std::stoi(argv[2]);
            aiManager.SetModel(model_id);
        } else {
            std::cout << "Usage: --ai-set-model <model_id> [model_name]" << std::endl;
        }
        return 0;
    }
    
    if (argc > 1 && std::string(argv[1]) == "--ai-mode") {
        if (argc > 2) {
            aiManager.AnalyzeProjectWithCode(argv[2]);
        } else {
            std::cout << "Usage: --ai-mode <cbp_file>" << std::endl;
        }
        return 0;
    }
    
    if (argc > 1 && std::string(argv[1]) == "--ai-status") {
        std::cout << aiManager.GetStatus() << std::endl;
        return 0;
    }
    
    if (argc > 1 && std::string(argv[1]) == "--ai-list-models") {
        std::cout << "Available AI Models:" << std::endl;
        std::cout << "  0: DeepSeek AI (DS-V3.2exp0922)" << std::endl;
        std::cout << "  1: UE CodeExpert" << std::endl;
        std::cout << "  2: GPT-4" << std::endl;
        return 0;
    }
    
    if (argc > 1 && (std::string(argv[1]) == "--help" || std::string(argv[1]) == "-h")) {
        std::cout << "cbp2make_ai - AI Enhanced CBP to Makefile Converter" << std::endl;
        std::cout << "Version: 4.0 (With Comment Generation)" << std::endl;
        std::cout << std::endl;
        std::cout << "NEW Comment Generation:" << std::endl;
        std::cout << "  --ai-generate-comments <file.cbp>  Generate code comments automatically" << std::endl;
        std::cout << std::endl;
        std::cout << "AI Features:" << std::endl;
        std::cout << "  --ai-deep-analysis <file.cbp>      Deep code analysis" << std::endl;
        std::cout << "  --ai-set-model <id> [name]         Set AI model" << std::endl;
        std::cout << "  --ai-mode <file.cbp>               AI analysis" << std::endl;
        std::cout << "  --ai-status                        Show AI status" << std::endl;
        std::cout << "  --ai-list-models                   List AI models" << std::endl;
        std::cout << std::endl;
        std::cout << "Examples:" << std::endl;
        std::cout << "  cbp2make_ai --ai-generate-comments project.cbp" << std::endl;
        std::cout << "  cbp2make_ai --ai-deep-analysis project.cbp" << std::endl;
        return 0;
    }
    
    std::cout << "cbp2make_ai v4.0 - Now with COMMENT GENERATION!" << std::endl;
    std::cout << "Use --ai-generate-comments to automatically generate code comments" << std::endl;
    std::cout << "Current AI Model: " << aiManager.GetStatus() << std::endl;
    
    return 0;
}
